import ODBC from './ODBC';
import sqlite from 'sqlite3';

const sqlite3 = sqlite.verbose();

class Sqlite3Promise extends ODBC {
    constructor(path: string, type = 'file') {
        super(path, type);
    }

    open() {
        if (this.db) {
            return this.db;
        } else if (this.type === 'memory') {
            this.db = new sqlite3.Database(':memory:');
            return this.db;
        } else if (this.type === 'file') {
            this.db = new sqlite3.Database(this.path);
        } else {
            console.log(`创建数据库失败，无法识别的类型${this.type}，仅支持：【file】 or 【memory】`);
            return null;
        }
    };

    async run(sqlStr: string, params?: any[]): Promise<{ lastID: string; changes: null }> {
        let that = this;
        return new Promise(function (resolve, reject) {
            if (!params) params = [];
            that.db.run(sqlStr, params, function (err: any) {
                if (err) {
                    console.log(err);
                    reject('执行SQL语句失败：' + err.message);
                } else {
                    // @ts-ignore
                    let { lastID, changes } = this;
                    resolve({ lastID, changes });
                }
            });
        });
    };


    // set of rows read
    async all(query: string, params: any): Promise<any[]> {
        let that = this;
        return new Promise(function (resolve, reject) {
            if (!params) params = [];
            that.db.all(query, params, function (err: any, row: any[]) {
                if (err) {
                    console.log(err);
                }

                resolve(row || []);
            });
        });
    }

    // 执行 SQL 语句，建表、修改数据库结构
    async exec(sql: string): Promise<boolean> {
        let that = this;
        return new Promise(function (resolve, reject) {
            that.db.exec(sql, function (err: any, rows: any) {
                if (err) {
                    reject('Read error: ' + err.message);
                } else {
                    resolve(true);
                }
            });
        });
    };


    async beginTransaction() {
        await this.exec('BEGIN TRANSACTION;;');
    };

    async commitTransaction() {
        await this.exec('COMMIT TRANSACTION;');
    };


    // var insertTileSql = "insert into tiles(level, column, row) values(?, ?, ?)";
    // var tileData = [1, 10, 10];
    async insertData(sql: string, tileData: any[]) {
        let that = this;
        return new Promise(function (resolve) {
            that.db.run(sql, tileData, function (err: any) {
                // @ts-ignore
                let { lastID, changes } = this;
                if (err) {
                    console.log(err);
                }
                resolve({ lastID, changes });
            });
        });
    };

    insertByParamsArr(sqlStr: string, objs: [][]): Promise<boolean> {
        return Promise.resolve(false);
    }

    async close(): Promise<boolean> {
        if (this.db && this.db.close) {
            return new Promise((resolve) => {
                this.db.close((err: any) => {
                    if (err) {
                        resolve(false);
                    } else {
                        resolve(true);
                    }
                });
            });
        } else {
            return false;
        }
    };

    backup(dbPath: string): Promise<boolean> {
        return Promise.resolve(false);
    }

    insertByObjs(sqlStr: string, objs: any[]): Promise<{ lastID: string; changes: null }> {
        return Promise.resolve({ changes: null, lastID: '' });
    }
}


export default Sqlite3Promise;
